* src/gdk-pixbuf-loader.c: Reorganize gdk_pixbuf_loader_write into three functions, and eliminate
duplication of code from write() and close(). Also fix bug where the 128-byte header was being
written twice.
-1999-11-01 Federico Mena Quintero <federico@redhat.com>
+1999-11-02 Elliot Lee <sopwith@redhat.com>
+ * src/gdk-pixbuf-loader.c: Reorganize gdk_pixbuf_loader_write into
+ three functions, and eliminate duplication of code from write()
+ and close(). Also fix bug where the 128-byte header was being
+ written twice.
+1999-11-01 Federico Mena Quintero <federico@redhat.com>
* src/gnome-canvas-pixbuf.c (recompute_bounding_box): Fixed
bounding box computation.
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
/* GdkPixbuf library - Main header file
*
* Copyright (C) 1999 The Free Software Foundation
\f
/* Internal data */
+
+#define LOADER_HEADER_SIZE 128
+
typedef struct {
GdkPixbuf *pixbuf;
gboolean closed;
- gchar buf[128];
- gint buf_offset;
+ gchar header_buf[LOADER_HEADER_SIZE];
+ gint header_buf_offset;
GdkPixbufModule *image_module;
gpointer context;
} GdkPixbufLoaderPrivate;
return gtk_type_new (gdk_pixbuf_loader_get_type ());
}
+static int
+gdk_pixbuf_loader_load_module(GdkPixbufLoader *loader)
+{
+ GdkPixbufLoaderPrivate *priv = loader->private;
+
+ priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset);
+
+ if (priv->image_module == NULL)
+ return 0;
+
+ if (priv->image_module->module == NULL)
+ gdk_pixbuf_load_module (priv->image_module);
+
+ if (priv->image_module->module == NULL)
+ return 0;
+
+ if ((priv->image_module->begin_load == NULL) ||
+ (priv->image_module->stop_load == NULL) ||
+ (priv->image_module->load_increment == NULL)) {
+ g_warning ("module %s does not support incremental loading.\n",
+ priv->image_module->module_name);
+ return 0;
+ }
+
+ priv->context = (*priv->image_module->begin_load) (gdk_pixbuf_loader_prepare, loader);
+
+ if (priv->context == NULL) {
+ g_warning("Failed to begin progressive load");
+ return 0;
+ }
+
+ if( (* priv->image_module->load_increment) (priv->context, priv->header_buf, priv->header_buf_offset) )
+ return priv->header_buf_offset;
+
+ return 0;
+}
+
+static int
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
+{
+ int nbytes;
+ GdkPixbufLoaderPrivate *priv = loader->private;
+
+ nbytes = MIN(LOADER_HEADER_SIZE - priv->header_buf_offset, count);
+ memcpy (priv->header_buf + priv->header_buf_offset, buf, nbytes);
+
+ priv->header_buf_offset += nbytes;
+
+ if(priv->header_buf_offset >= LOADER_HEADER_SIZE) {
+ return gdk_pixbuf_loader_load_module(loader);
+ } else
+ return nbytes;
+}
+
/**
* gdk_pixbuf_loader_write:
* @loader: A pixbuf loader.
g_return_val_if_fail (loader != NULL, FALSE);
g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE);
+
g_return_val_if_fail (buf != NULL, FALSE);
g_return_val_if_fail (count >= 0, FALSE);
g_return_val_if_fail (priv->closed == FALSE, FALSE);
if (priv->image_module == NULL) {
- gboolean retval = TRUE;
-
- memcpy (priv->buf + priv->buf_offset,
- buf,
- (priv->buf_offset + count > 128) ? (128 - priv->buf_offset) : count);
-
- if (priv->buf_offset + count >= 128) {
- /* We have enough data to start doing something with the image */
- priv->image_module = gdk_pixbuf_get_module (priv->buf, 128);
- if (priv->image_module == NULL)
- return FALSE;
- else if (priv->image_module->module == NULL)
- gdk_pixbuf_load_module (priv->image_module);
-
- if ((priv->image_module->begin_load == NULL) ||
- (priv->image_module->stop_load == NULL) ||
- (priv->image_module->load_increment == NULL)) {
- g_warning ("module %s does not support incremental loading.\n",
- priv->image_module->module_name);
- return FALSE;
- } else {
- priv->context = (*priv->image_module->begin_load) (
- gdk_pixbuf_loader_prepare, loader);
-
- if (priv->context == NULL) {
- g_warning("Failed to begin progressive load");
- return FALSE;
- }
-
- retval = (* priv->image_module->load_increment) (
- priv->context, priv->buf, 128);
-
- /* if we had more then 128 bytes total, we want
- * to send the rest of the buffer.
- */
-
- if (retval && (priv->buf_offset + count) > 128) {
- retval = (* priv->image_module->load_increment) (
- priv->context,
- buf,
- count + priv->buf_offset - 128);
- }
- }
- } else
- priv->buf_offset += count;
-
- return retval;
+ int eaten;
+
+ eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count);
+ if (eaten <= 0)
+ return FALSE;
+
+ count -= eaten;
+ buf += eaten;
}
- if (priv->image_module->load_increment)
+ if (count > 0 && priv->image_module->load_increment)
return (* priv->image_module->load_increment) (priv->context, buf, count);
return (FALSE);
g_return_if_fail (priv->closed == FALSE);
/* We have less the 128 bytes in the image. Flush it, and keep going. */
- if (priv->image_module == NULL) {
- priv->image_module = gdk_pixbuf_get_module (priv->buf, priv->buf_offset);
- if (priv->image_module &&
- ((priv->image_module->begin_load == NULL) ||
- (priv->image_module->stop_load == NULL) ||
- (priv->image_module->load_increment == NULL))) {
- g_warning ("module %s does not support incremental loading.\n",
- priv->image_module->module_name);
- } else if (priv->image_module) {
- g_print ("module loaded: name is %s\n", priv->image_module->module_name);
- priv->context = (* priv->image_module->begin_load) (
- gdk_pixbuf_loader_prepare, loader);
- (* priv->image_module->load_increment) (priv->context,
- priv->buf, priv->buf_offset);
- }
- }
+ if (priv->image_module == NULL)
+ gdk_pixbuf_loader_load_module (loader);
if (priv->image_module && priv->image_module->stop_load)
(* priv->image_module->stop_load) (priv->context);
#include <config.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
#include <setjmp.h>
#include <jpeglib.h>
#include "gdk-pixbuf.h"
\f
/* we are a "source manager" as far as libjpeg is concerned */
+#define JPEG_PROG_BUF_SIZE 4096
+
typedef struct {
struct jpeg_source_mgr pub; /* public fields */
- JOCTET * buffer; /* start of buffer */
- gboolean start_of_file; /* have we gotten any data yet? */
+ JOCTET buffer[JPEG_PROG_BUF_SIZE]; /* start of buffer */
long skip_next; /* number of bytes to skip next read */
-
+
} my_source_mgr;
typedef my_source_mgr * my_src_ptr;
struct error_handler_data jerr;
} JpegProgContext;
-#define JPEG_PROG_BUF_SIZE 4096
-
GdkPixbuf *image_load (FILE *f);
gpointer image_begin_load (ModulePreparedNotifyFunc func, gpointer user_data);
void image_stop_load (gpointer context);
{
my_src_ptr src = (my_src_ptr) cinfo->src;
- src->start_of_file = TRUE;
src->skip_next = 0;
}
JpegProgContext *context;
my_source_mgr *src;
- context = g_new (JpegProgContext, 1);
+ context = g_new0 (JpegProgContext, 1);
context->notify_func = func;
context->notify_user_data = user_data;
context->pixbuf = NULL;
/* create libjpeg structures */
jpeg_create_decompress (&context->cinfo);
- context->cinfo.src = (struct jpeg_source_mgr *) g_new (my_source_mgr, 1);
+ context->cinfo.src = (struct jpeg_source_mgr *) g_new0 (my_source_mgr, 1);
src = (my_src_ptr) context->cinfo.src;
- src->buffer = g_malloc (JPEG_PROG_BUF_SIZE);
context->cinfo.err = jpeg_std_error (&context->jerr.pub);
image_stop_load (gpointer data)
{
JpegProgContext *context = (JpegProgContext *) data;
+
g_return_if_fail (context != NULL);
if (context->pixbuf)
if (context->cinfo.src) {
my_src_ptr src = (my_src_ptr) context->cinfo.src;
- if (src->buffer)
- g_free (src->buffer);
g_free (src);
}
struct jpeg_decompress_struct *cinfo;
my_src_ptr src;
guint num_left, num_copy;
- guchar *nextptr;
g_return_val_if_fail (context != NULL, FALSE);
g_return_val_if_fail (buf != NULL, FALSE);
src = (my_src_ptr) context->cinfo.src;
+
cinfo = &context->cinfo;
/* skip over data if requested, handle unsigned int sizes cleanly */
while (num_left > 0) {
/* copy as much data into buffer as possible */
- num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
- size);
- if (num_copy == 0)
- g_assert ("Buffer overflow!\n");
+ if(src->pub.bytes_in_buffer)
+ {
+ int space_used =
+ JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer;
- nextptr = src->buffer + src->pub.bytes_in_buffer;
- memcpy (nextptr, buf, num_copy);
-
- if (src->pub.next_input_byte == NULL ||
- src->pub.bytes_in_buffer == 0)
- src->pub.next_input_byte = src->buffer;
+ memmove(src->buffer, src->buffer + space_used, src->pub.bytes_in_buffer);
+ g_print("Moving %d bytes from offset %d to head\n", src->pub.bytes_in_buffer, space_used);
+ }
+ num_copy = MIN (JPEG_PROG_BUF_SIZE - src->pub.bytes_in_buffer,
+ size);
+ if (num_copy == 0)
+ g_error ("Buffer overflow!");
+ memcpy(src->buffer + src->pub.bytes_in_buffer, buf, num_copy);
+ src->pub.next_input_byte = src->buffer;
src->pub.bytes_in_buffer += num_copy;
-
num_left -= num_copy;
+ g_print("Copied %d bytes, now have %d in buffer, %d left\n", num_copy, src->pub.bytes_in_buffer, num_left);
+ G_BREAKPOINT();
/* try to load jpeg header */
if (!context->got_header) {
rc = jpeg_read_header (cinfo, TRUE);
context->src_initialized = TRUE;
+
if (rc == JPEG_SUSPENDED)
continue;
if (context->pixbuf == NULL) {
/* Failed to allocate memory */
- g_assert ("Couldn't allocate gdkpixbuf\n");
+ g_error ("Couldn't allocate gdkpixbuf");
}
/* Use pixbuf buffer to store decompressed data */
(* context->notify_func) (context->pixbuf,
context->notify_user_data);
- src->start_of_file = FALSE;
} else if (!context->did_prescan) {
int rc;
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
/* GdkPixbuf library - Main header file
*
* Copyright (C) 1999 The Free Software Foundation
\f
/* Internal data */
+
+#define LOADER_HEADER_SIZE 128
+
typedef struct {
GdkPixbuf *pixbuf;
gboolean closed;
- gchar buf[128];
- gint buf_offset;
+ gchar header_buf[LOADER_HEADER_SIZE];
+ gint header_buf_offset;
GdkPixbufModule *image_module;
gpointer context;
} GdkPixbufLoaderPrivate;
return gtk_type_new (gdk_pixbuf_loader_get_type ());
}
+static int
+gdk_pixbuf_loader_load_module(GdkPixbufLoader *loader)
+{
+ GdkPixbufLoaderPrivate *priv = loader->private;
+
+ priv->image_module = gdk_pixbuf_get_module (priv->header_buf, priv->header_buf_offset);
+
+ if (priv->image_module == NULL)
+ return 0;
+
+ if (priv->image_module->module == NULL)
+ gdk_pixbuf_load_module (priv->image_module);
+
+ if (priv->image_module->module == NULL)
+ return 0;
+
+ if ((priv->image_module->begin_load == NULL) ||
+ (priv->image_module->stop_load == NULL) ||
+ (priv->image_module->load_increment == NULL)) {
+ g_warning ("module %s does not support incremental loading.\n",
+ priv->image_module->module_name);
+ return 0;
+ }
+
+ priv->context = (*priv->image_module->begin_load) (gdk_pixbuf_loader_prepare, loader);
+
+ if (priv->context == NULL) {
+ g_warning("Failed to begin progressive load");
+ return 0;
+ }
+
+ if( (* priv->image_module->load_increment) (priv->context, priv->header_buf, priv->header_buf_offset) )
+ return priv->header_buf_offset;
+
+ return 0;
+}
+
+static int
+gdk_pixbuf_loader_eat_header_write (GdkPixbufLoader *loader, guchar *buf, size_t count)
+{
+ int nbytes;
+ GdkPixbufLoaderPrivate *priv = loader->private;
+
+ nbytes = MIN(LOADER_HEADER_SIZE - priv->header_buf_offset, count);
+ memcpy (priv->header_buf + priv->header_buf_offset, buf, nbytes);
+
+ priv->header_buf_offset += nbytes;
+
+ if(priv->header_buf_offset >= LOADER_HEADER_SIZE) {
+ return gdk_pixbuf_loader_load_module(loader);
+ } else
+ return nbytes;
+}
+
/**
* gdk_pixbuf_loader_write:
* @loader: A pixbuf loader.
g_return_val_if_fail (loader != NULL, FALSE);
g_return_val_if_fail (GDK_IS_PIXBUF_LOADER (loader), FALSE);
+
g_return_val_if_fail (buf != NULL, FALSE);
g_return_val_if_fail (count >= 0, FALSE);
g_return_val_if_fail (priv->closed == FALSE, FALSE);
if (priv->image_module == NULL) {
- gboolean retval = TRUE;
-
- memcpy (priv->buf + priv->buf_offset,
- buf,
- (priv->buf_offset + count > 128) ? (128 - priv->buf_offset) : count);
-
- if (priv->buf_offset + count >= 128) {
- /* We have enough data to start doing something with the image */
- priv->image_module = gdk_pixbuf_get_module (priv->buf, 128);
- if (priv->image_module == NULL)
- return FALSE;
- else if (priv->image_module->module == NULL)
- gdk_pixbuf_load_module (priv->image_module);
-
- if ((priv->image_module->begin_load == NULL) ||
- (priv->image_module->stop_load == NULL) ||
- (priv->image_module->load_increment == NULL)) {
- g_warning ("module %s does not support incremental loading.\n",
- priv->image_module->module_name);
- return FALSE;
- } else {
- priv->context = (*priv->image_module->begin_load) (
- gdk_pixbuf_loader_prepare, loader);
-
- if (priv->context == NULL) {
- g_warning("Failed to begin progressive load");
- return FALSE;
- }
-
- retval = (* priv->image_module->load_increment) (
- priv->context, priv->buf, 128);
-
- /* if we had more then 128 bytes total, we want
- * to send the rest of the buffer.
- */
-
- if (retval && (priv->buf_offset + count) > 128) {
- retval = (* priv->image_module->load_increment) (
- priv->context,
- buf,
- count + priv->buf_offset - 128);
- }
- }
- } else
- priv->buf_offset += count;
-
- return retval;
+ int eaten;
+
+ eaten = gdk_pixbuf_loader_eat_header_write(loader, buf, count);
+ if (eaten <= 0)
+ return FALSE;
+
+ count -= eaten;
+ buf += eaten;
}
- if (priv->image_module->load_increment)
+ if (count > 0 && priv->image_module->load_increment)
return (* priv->image_module->load_increment) (priv->context, buf, count);
return (FALSE);
g_return_if_fail (priv->closed == FALSE);
/* We have less the 128 bytes in the image. Flush it, and keep going. */
- if (priv->image_module == NULL) {
- priv->image_module = gdk_pixbuf_get_module (priv->buf, priv->buf_offset);
- if (priv->image_module &&
- ((priv->image_module->begin_load == NULL) ||
- (priv->image_module->stop_load == NULL) ||
- (priv->image_module->load_increment == NULL))) {
- g_warning ("module %s does not support incremental loading.\n",
- priv->image_module->module_name);
- } else if (priv->image_module) {
- g_print ("module loaded: name is %s\n", priv->image_module->module_name);
- priv->context = (* priv->image_module->begin_load) (
- gdk_pixbuf_loader_prepare, loader);
- (* priv->image_module->load_increment) (priv->context,
- priv->buf, priv->buf_offset);
- }
- }
+ if (priv->image_module == NULL)
+ gdk_pixbuf_loader_load_module (loader);
if (priv->image_module && priv->image_module->stop_load)
(* priv->image_module->stop_load) (priv->context);